package com.alpha.common.controller;

import com.alpha.common.schemas.groups.GroupService;
import com.alpha.common.schemas.menus.Menu;
import com.alpha.common.schemas.menus.MenuService;
import com.alpha.common.schemas.organizations.Organization;
import com.alpha.common.schemas.organizations.OrganizationService;
import com.alpha.common.schemas.resources.Resource;
import com.alpha.common.schemas.resources.ResourceService;
import com.alpha.common.schemas.tenants.Tenant;
import com.alpha.common.schemas.tenants.TenantService;
import com.alpha.common.schemas.users.*;
import com.alpha.core.http.AlphaHttpContext;
import com.alpha.core.http.Response;
import com.alpha.core.utils.CollectionUtil;
import com.alpha.service.utils.MyBatisPlusUtils;
import com.alpha.core.utils.StringUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import java.util.stream.Collectors;

/**
 * 扩展用户接口
 *
 * @author chenruwan
 * @since 2022-01-01
 */
@Tag(name = "用户")
@RestController
public class UserController extends UserMappings {
    private final TenantService tenantService;
    private final MenuService menuService;
    private final ResourceService resourceService;

    @Autowired
    public UserController(UserService userService, UserOrganizationService userOrganizationService,
                          OrganizationService organizationService, UserGroupService userGroupService,
                          GroupService groupService, TenantService tenantService,
                          MenuService menuService, ResourceService resourceService) {
        super(userService, userOrganizationService, organizationService, userGroupService, groupService);
        this.tenantService = tenantService;
        this.menuService = menuService;
        this.resourceService = resourceService;
    }

    /**
     * 支持控制企业用户数
     */
    @Override
    public synchronized Response<Long> save(@Validated @RequestBody User user) {
        String tenantId = AlphaHttpContext.getTenantId();
        user.setTenantId(tenantId == null ? null : Long.valueOf(tenantId));
        if (user.getTenantId() != null) {
            Tenant tenant = tenantService.getById(user.getTenantId());
            if (tenant == null) {
                return Response.failure(HttpStatus.BAD_REQUEST, "未查询到企业相关信息");
            }
            long count = userService.count(new LambdaQueryWrapper<User>().eq(User::getTenantId, user.getTenantId()));
            if (count >= tenant.getAccountLimit()) {
                return Response.failure(HttpStatus.BAD_REQUEST, "企业账户数已达上限，请联系系统管理员");
            }
        }
        return super.save(user);
    }

    @GetMapping("/users/menus")
    @Operation(summary = "获取用户所有菜单")
    public Response<List<Menu>> getMenus(@RequestParam Long userId) {
        User user = userService.getById(userId);
        if (user == null) {
            return Response.success(CollectionUtil.emptyList());
        }

        // 支持部门和岗位的权限继承
        List<Organization> positions = userOrganizationService.getUserOrganizations(userId).stream()
                .map(UserOrganization::getOrganization).collect(Collectors.toList());
        List<Long> parentIds = CollectionUtil.extractField(positions, Organization::getParentId);
        while (CollectionUtil.isNotEmpty(parentIds)) {
            List<Organization> parents = organizationService.listByIds(parentIds);
            positions.addAll(parents);
            parentIds = CollectionUtil.extractField(parents, Organization::getParentId);
        }

        Set<Long> menusIds = new TreeSet<>(CollectionUtil.emptyIfNull(user.getMenus()));
        menusIds.addAll(positions.stream()
                .flatMap(e -> CollectionUtil.emptyIfNull(e.getMenus()).stream())
                .collect(Collectors.toList()));

        menusIds.addAll(userGroupService.getUserGroups(userId)
                .stream().map(UserGroup::getGroup)
                .flatMap(e -> CollectionUtil.emptyIfNull(e.getMenus()).stream())
                .collect(Collectors.toList()));

        return Response.success(MyBatisPlusUtils.listByIds(menuService, menusIds));
    }

    @GetMapping("/users/resources")
    @Operation(summary = "获取用户所有资源")
    public Response<List<Resource>> getResources(@RequestParam String userId) {
        String id = AlphaHttpContext.getUserId();
        if (StringUtil.isEmpty(id)) {
            id = userId;
        }

        Set<Long> resourceIds = getMenus(Long.valueOf(id)).getData().stream()
                .flatMap(e -> CollectionUtil.emptyIfNull(e.getResources()).stream())
                .collect(Collectors.toSet());

        return Response.success(MyBatisPlusUtils.listByIds(resourceService, resourceIds));
    }
}
